from rest_framework_simplejwt.views import (
    TokenObtainPairView as TokenView,
    TokenRefreshView as RefreshTokenView
)
from rest_framework_simplejwt.exceptions import TokenError
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer as Token
from django.conf import settings

from rest_framework.generics import GenericAPIView
from rest_framework.viewsets import GenericViewSet

from . import mixins
from .response import response
from . import Code


class TokenObtainPairView(TokenView):
    serializer_class = Token

    def post(self, request, *args, **kwargs):
        """登录"""
        ret = super().post(request, *args, **kwargs)
        return response(data=ret.data)


class TokenRefreshView(RefreshTokenView):
    def post(self, request, *args, **kwargs):
        """refresh 获取 access"""
        serializer = self.get_serializer(data=request.data)

        try:
            serializer.is_valid(raise_exception=True)
        except TokenError:
            return response(code=Code.C_4_10, message='令牌过期或失效')

        return response(data=serializer.validated_data)


class ListAPIView(mixins.ListModelMixin, GenericAPIView):
    """分页View"""

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)


class RetrieveAPIView(mixins.RetrieveModelMixin, GenericAPIView):
    """查询单个"""

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)


class CreateUpdateDeleteAPIView(
    mixins.CreateModelMixin,
    mixins.UpdateModelMixin,
    mixins.DestroyModelMixin,
    GenericAPIView
):
    """创建数据、修改、删除 根据后缀 post/put/delete/ 处理增删改"""
    methods = settings.METHODS_MAP

    def post(self, request, *args, **kwargs):
        """
        请求方式 -> 方法映射
        :param request:
        :param args:
        :param kwargs:
        :return:
        example
            url -> /user/post/ 创建 -> rest framework mixins create
            url -> /user/<int:pk>/put/ 修改 -> rest framework mixins  update
            url -> /user<int:pk>/delete/ 删除 -> rest framework mixins  destroy
        """
        method = kwargs.get('method')
        if not method in self.methods:
            return response(message='fail', code=Code.C_4_5)

        func = getattr(self, self.methods.get(method))
        return func(request, *args, **kwargs)


class ListModelViewSets(
    mixins.ListModelMixin,
    mixins.SelectMixin,
    GenericViewSet
):
    """
    根据全局分页、下拉框对应接口
    """


class DeleteModelViewSets(
    mixins.DeleteBatchMixin,
    mixins.DestroyModelMixin,
    GenericViewSet
):
    """
    删除多个
    """


class UpdateModelViewSets(
    mixins.UpdateModelMixin,
    mixins.PuBatchMixin,
    GenericViewSet
):
    """
    修改单个、多个
    """


class ModelViewSets(
    mixins.CreateModelMixin,
    mixins.RetrieveModelMixin,
    mixins.UpdateModelMixin,
    mixins.PuBatchMixin,
    mixins.DestroyModelMixin,
    mixins.ListModelMixin,
    mixins.SelectMixin,
    mixins.DeleteBatchMixin,
    GenericViewSet
):
    """
    全局分页、单个查询、创建、修改、单个、多个删除、下拉框
    """
